/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/** ************************************************************************************************
 * @file     Semag.h                                                                               *
 * @brief    This file contains interface header for Semaphore Gate driver                         *
 *                                                                                                 *
 **************************************************************************************************/

#ifndef SEMAG_H
#define SEMAG_H

/***************************************************************************************************
 *                                      Include header files                                       *
 **************************************************************************************************/
#include "lld_platform.h"
#include "mbox_proc.h"

/***************************************************************************************************
 *                                 Global Macro definition                                         *
 **************************************************************************************************/
/** @brief  semaphore gate total number */
#define SDRV_SEMAG_NUM (32UL)

/** @brief  mram driver used semag index */
#define SDRV_SEMAG_MRAM   (0UL)
/** @brief  xspi driver used semag index */
#define SDRV_SEMAG_XSPI   (1UL)
/** @brief  scr driver used semag index */
#define SDRV_SEMAG_SCR    (2UL)
/** @brief  gic driver used semag index */
#define SDRV_SEMAG_GIC    (3UL)
/** @brief  uart driver used semag index */
#define SDRV_SEMAG_UART   (4UL)
/** @brief  crypto driver used semag index */
#define SDRV_SEMAG_CRYPTO (5UL)

#if defined (CFG_PLATFORM_MCAL)
/** \brief  ERROR Description:invalid param */
#define SEMAG_E_INVALID_PARAM (0x01U)
/** \brief  ERROR Description:Status ok */
#define SEMAG_E_OK (0x00U)
/** \brief  ERROR Description:status fail */
#define SEMAG_E_FAIL (0xffU)
#elif defined (CFG_PLATFORM_SSDK)
/** \brief  ERROR Description:invalid param */
#define SEMAG_E_INVALID_PARAM SDRV_STATUS_INVALID_PARAM
/** \brief  ERROR Description:Status ok */
#define SEMAG_E_OK SDRV_STATUS_OK
/** \brief  ERROR Description:status fail */
#define SEMAG_E_FAIL SDRV_STATUS_FAIL
#else
#error "Undefined macros CFG_PLATFORM_MCAL or CFG_PLATFORM_SSDK"
#endif /** #if defined (CFG_PLATFORM_MCAL) */

/***************************************************************************************************
 *                                  Global Function Declarations                                   *
 **************************************************************************************************/
/**
 * @brief Tries to lock the SEMAG gate.
 *
 * This function tries to lock the specific SEMAG gate. If the gate has been
 * locked by another processor, this function returns an error code.
 *
 * @param [in] gate_idx  Gate number to lock.
 * @return SEMAG_E_INVALID_PARAM  The gate id is unvalid.
 *         SEMAG_E_FAIL  Semag gate has been locked by another processor.
 *         SEMAG_E_OK  Lock the semag gate successfully.
 */
lld_status_t sdrv_semag_trylock(uint32_t gate_idx);

/**
 * @brief Locks the SEMAG gate.
 *
 * This function locks the specific SEMAG gate. If the gate has been
 * locked by other processors, this function waits until it is unlocked and then
 * lock it.
 *
 * @param [in] gate_idx  Gate number to lock.
 * @return SEMAG_E_INVALID_PARAM  The gate id is unvalid.
 *         SEMAG_E_OK  Lock the semag gate successfully.
 */
lld_status_t sdrv_semag_lock(uint32_t gate_idx);

/**
 * @brief Unlocks the SEMAG gate.
 *
 * This function unlocks the specific SEMAG gate. It only writes unlock value
 * to the SEMAG gate register. However, it does not check whether the SEMAG gate
 * is locked by the current processor or not. As a result, if the SEMAG gate is
 * not locked by the current processor, this function has no effect.
 *
 * @param [in] gate_idx  Gate number to unlock.
 * @return SEMAG_E_OK Unlock the semag gate successfully.
 */
lld_status_t sdrv_semag_unlock(uint32_t gate_idx);

/**
 * @brief Gets the status of the SEMAG gate.
 *
 * This function checks the lock status of a specific SEMAG gate.
 *
 * @param [in] gate_idx  Gate number to check lock status.
 * @return Return -1 if the gate is unlocked, otherwise return the
 * processor number which has locked the gate.
 */
int32_t sdrv_semag_get_lock_proc(uint32_t gate_idx);

/**
 * @brief Resets all SEMAG gates to an unlocked status.
 *
 * This function resets all SEMAG gate to an unlocked status,
 * it will only unlock gates which locked by itself, can't reset
 * gates which locked by other processors.
 * @return SEMAG_E_OK Reset all semag gates successfully.
 */
lld_status_t sdrv_semag_reset_all_gate(void);

/**
 * @brief Enable the gate notification interrupt.
 *
 * Gate notification provides such feature, when interrupt is enabled, then core
 * tried to lock the gate and failed, it could get notification when the gate is
 * idle.
 *
 * @param [in] mask Mask of the gate index, for example: (1<<0U) | (1<<1U)
 * means gate 0 and gate 1.
 * @return SEMAG_E_OK Enable the notify interrupt of the semag gate
 * successfully.
 */
lld_status_t sdrv_semag_enable_gate_notify_interrupt(uint32_t mask);

/**
 * @brief Disable the gate notification interrupt.
 *
 * Gate notification provides such feature, when interrupt is enabled, then core
 * tried to lock the gate and failed, it could get notification when the gate is
 * idle.
 *
 * @param [in] mask Mask of the gate index, for example: (1<<0U) | (1<<1U)
 * means gate 0 and gate 1.
 * @return SEMAG_E_OK Disable the notify interrupt of the semag gate
 * successfully.
 */
lld_status_t sdrv_semag_disable_gate_notify_interrupt(uint32_t mask);

/**
 * @brief Get the gate notification flags.
 *
 * Gate notification provides such feature, when interrupt is enabled, then core
 * tried to lock the gate and failed, it could get notification when the gate is
 * idle.
 *
 * @return Mask of the gate index, for example: (1<<0U) | (1<<1U) means
 * gate 0 and gate 1 flags are pending.
 */
uint32_t sdrv_semag_get_notify_status(void);

/**
 * @brief Clear the gate notification interrupt status.
 *
 * This function clear SEMAG gate IRQ notifications.
 *
 * @param [in] mask Mask of the gate index, for example: (1<<0U) | (1<<1U)
 * means gate 0 and gate 1.
 * @return SEMAG_E_OK Clear the notify interrupt status of the semag gate
 * successfully.
 */
lld_status_t sdrv_semag_clear_notify_status(uint32_t mask);

#endif /* #ifndef SEMAG_H */
/* End of file */
